package com.example.lockpatternview;


import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug.FlagToString;

public class LockPatternView extends View {
	//选中点的数量
	private static final int POINT_SIZE = 5;

	//矩阵
	private Matrix matrix = new Matrix();

	//创建画笔
	private Paint paint = new Paint();
	//9个点
	private Point[][] points = new Point[3][3];
	private boolean isInit,isSelect,isFinish,movingNoPoint;
	private float width,height,offsetsX,offsetsY,bitmapR,movingX,movingY;;

	private Bitmap pointNarmal,pointPressed,pointError,linePressed,lineError;
	//按下点集合
	private List<Point> pointList = new ArrayList<Point>();

	public LockPatternView(Context context) {
		super(context);

	}
	public LockPatternView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public LockPatternView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		if(!isInit){
			initPoints();
		}
		//画点

		points2Canvas(canvas);
		//画线
		if(pointList.size() > 0){
			Point a = pointList.get(0);
			//绘制9宫格点
			for(int i = 0;i < pointList.size();i++){
				Point b = pointList.get(i);
				line2Canvas(canvas, a, b);
				a = b;
			}
			//绘制鼠标点
			if(movingNoPoint){
				line2Canvas(canvas, a, new Point(movingX, movingY));
			}
		}
	}

	//初始化点
	public void initPoints() {
		//获取屏幕宽高
		width = getWidth();
		height = getHeight();

		//判断横屏竖屏
		//横屏
		if(width > height){
			offsetsX = (width-height)/2;
			width = height;

			//竖屏
		}else{
			offsetsY = (height-width)/2;
			height = width;
		}

		//图片资源
		pointNarmal = BitmapFactory.decodeResource(getResources(), R.drawable.normal);
		pointPressed = BitmapFactory.decodeResource(getResources(), R.drawable.pressed);
		pointError = BitmapFactory.decodeResource(getResources(), R.drawable.error);

		linePressed = BitmapFactory.decodeResource(getResources(), R.drawable.line2);
		lineError = BitmapFactory.decodeResource(getResources(), R.drawable.error2);

		//点坐标
		points[0][0] = new Point(offsetsX + width/4,offsetsY + width/4);//           00  01  02
		points[0][1] = new Point(offsetsX + width/2,offsetsY + width/4);//           10  11  12
		points[0][2] = new Point(offsetsX + width - width/4,offsetsY + width/4);//   20  21  22

		points[1][0] = new Point(offsetsX + width/4,offsetsY + width/2);//
		points[1][1] = new Point(offsetsX + width/2,offsetsY + width /2);//
		points[1][2] = new Point(offsetsX + width - width/4,offsetsY + width/2);//

		points[2][0] = new Point(offsetsX + width/4,offsetsY + width - width/4);//
		points[2][1] = new Point(offsetsX + width/2,offsetsY + width - width/4);//
		points[2][2] = new Point(offsetsX + width - width/4,offsetsY + width - width/4);//



		//图片资源半径
		bitmapR =pointNarmal.getWidth()/2;

		isInit = true;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		movingNoPoint = false;
		isFinish = false;
		movingX = event.getX();
		movingY = event.getY();

		Point point = null;
		switch (event.getAction()) {
			case MotionEvent.ACTION_DOWN:
				isFinish = false;
				resetPoint();
				point = checkSelectPoint();
				if(point != null){
					isSelect = true;
				}
				break;
			case MotionEvent.ACTION_MOVE:
				if(isSelect){
					point = checkSelectPoint();
					if(point != null){
						movingNoPoint = true;
					}
				}
				break;
			case MotionEvent.ACTION_UP:
				isFinish = true;
				isSelect = false;
				break;
		}
		/**
		 * 选中重复检查
		 */
		if(!isFinish && isSelect && point != null){
			//交叉点
			if(crossPoint(point)){
				movingNoPoint = true;
				//新点
			}else{
				point.state = Point.STATE_PRESSED;
				pointList.add(point);
			}
		}
		/**
		 * 绘制结束
		 */
		if(isFinish){
			if(pointList.size() == 1){
				resetPoint();
				//绘制错误
			}else if(pointList.size() < POINT_SIZE && pointList.size() > 2){
				errorPoint();
			}
			//刷新
			postInvalidate();
		}
		return true;
	}
	//交叉点检查
	public boolean crossPoint(Point point){
		if(pointList.contains(point)){
			return true;
		}else {
			return false;
		}
	}
	//设置绘制不成立
	public void resetPoint(){
		for(int i = 0;i < pointList.size();i++){
			Point point = pointList.get(i);
			point.state = Point.STATE_NORMAL;
		}
		pointList.clear();
	}
	//设置绘制错误
	public void errorPoint(){
		for(Point point:pointList){
			point.state = Point.STATE_ERROR;
		}
	}
	/**
	 * 检查是否选中
	 * @return
	 */
	public Point checkSelectPoint(){
		for(int i = 0;i < points.length;i++){
			for(int j = 0;j < points[i].length;j++){
				Point point = points[i][j];
				if(Point.with(point.x, point.y, bitmapR, movingX, movingY)){
					return point;
				}
			}

		}
		return null;
	}
	/**
	 * 获取角度
	 * a 
	 * b
	 */
	public float getDegrees(Point a,Point b) {
		float ax = a.x;
		float ay = a.y;
		float bx = b.x;
		float by = b.y;
		float degrees = 0;
		if(bx == ax){//X相等 90度或270度
			if(by == ay){//在Y轴下边 90
				degrees =90;
			}else if(by <ay){//在y轴上边 270
				degrees = 270;
			}
		}else if (by == ay) {//y轴相等 0度或180
			if (bx >ax ) {//在x轴下边 0
				degrees = 0;
			}else if (bx < ax ) {//在x轴上边180
				degrees = 180;
			}
		}
		return degrees;
	}

	/**
	 * 将点划在画布上
	 * @param canvas
	 * @param a 第一点
	 * @param b 第二点
	 */
	public void line2Canvas(Canvas canvas,Point a,Point b){

		//绘制线长度
		float lineLength = (float) Point.distance(a, b);
		float degrees = getDegrees(a, b);
		canvas.rotate(degrees, a.x, a.y);//旋转画布实现角度旋转
		if(a.state == Point.STATE_PRESSED){
			matrix.setScale(lineLength/linePressed.getWidth(), 1);
			matrix.postTranslate(a.x - linePressed.getWidth()/2, a.y - linePressed.getHeight()/2);
			canvas.drawBitmap(linePressed, matrix, paint);
		}else{
			matrix.setScale(lineLength/lineError.getWidth(), 1);
			matrix.postTranslate(a.x - lineError.getWidth()/2, a.y - lineError.getHeight()/2);
			canvas.drawBitmap(lineError, matrix, paint);
		}
		canvas.rotate(-degrees, a.x, a.y);//画布转回
	}
	//将点绘制在画布
	public void points2Canvas(Canvas canvas) {
		for(int i= 0;i < points.length;i++){
			for(int j = 0;j < points[i].length;j++){
				Point point = points[i][j];
				if (point.state == Point.STATE_PRESSED) {
					canvas.drawBitmap(pointPressed, point.x - bitmapR, point.y, paint);
				}else if(point.state == Point.STATE_ERROR){
					canvas.drawBitmap(pointError, point.x - bitmapR, point.y, paint);
				}else{
					canvas.drawBitmap(pointNarmal, point.x - bitmapR, point.y, paint);
				}
			}
		}
	}
	/*
	 * 自定义点
	 */
	public static class Point{
		//正常
		public static int STATE_NORMAL = 0;
		//选中
		public static int STATE_PRESSED = 1;
		//错误
		public static int STATE_ERROR = 2;
		public float x,y;
		public int index = 0,state = 0;
		public Point(){

		}
		public  Point(float x,float y) {
			this.x = x;
			this.y = y;
		}
		/**
		 * a点与b点距离
		 * 勾股定律
		 */
		public static double distance(Point a,Point b){
			return Math.sqrt(Math.abs(a.x - b.x) * Math.abs(a.x - b.x)
					+ Math.abs(a.y - b.y) * Math.abs(a.y - b.y));
		}
		/**
		 * pointX参考点x
		 * pointY参考点Y
		 * r     圆的半径
		 * movingX 移动点的X
		 * movingY 移动点的Y
		 * 判断是否重合
		 */
		public static boolean with(float pointX,float pointY,float r,float movingX,float movingY){
			return Math.sqrt((pointX - movingX) * (pointX - movingX)
					+(pointY - movingY) * (pointY - movingY)) < r;
		}

	}


}

